<template>
  <page-content center>
    <div style="overflow-x: auto;">
      <space class="my-1 header-actions">
        <a-button @click="onExpand">展开</a-button>
        <a-button @click="onCollapse">收起</a-button>
        <a-upload
          name="file"
          :custom-request="importSystemModels"
          :show-upload-list="false"
          :before-upload="confirmImport"
        >
          <a-button>导入</a-button>
        </a-upload>
        <a-button @click="onExport">导出</a-button>
      </space>

      <nested-draggable
        ref="models"
        :expand-keys="defaultExpanded"
        class="system-models"
        :list="SystemModels"
        :disabled="true"
      >
        <template #default="{ data }">
          <div v-if="data.parent_id==0" class="item-wrap">
            <span class="ml-1">{{ data.slug }}</span>
            <span class="ml-1">{{ data.name }}</span>
          </div>
          <div v-else class="item-wrap">
            <children-field :data="data" :drag="false"/>
          </div>
          <div class="flex-spacer"/>
          <space>
            <doc-preview
              :label="`字段总览`"
              :title="`字段总览`"
              :content="fields[data.id]"
            />
            <doc-preview
              :label="`字段类型总览`"
              :title="`字段类型总览`"
              :content="fieldTypes[data.id]"
            />
            <doc-preview
              :label="`验证规则总览`"
              :title="`验证规则总览`"
              :content="validationRules[data.id]"
            />
            <doc-preview
              :label="`筛选规则总览`"
              :title="`筛选规则总览`"
              :content="filterRules[data.id]"
            />
            <router-link v-if="data.parent_id==0" target='_blank' :to="`/system-models/${data.id}`">
              <a-button>查看字段</a-button>
            </router-link>
            <space v-else>
             <router-link target='_blank' :to="`/system-models/${data.parent_id}/edit?id=${data.id}`">编辑</router-link>
              <lz-popconfirm v-if="data.is_virtual" :confirm="onDestroy(data)" title="删除该虚拟字段">
                <a class="error-color" href="javascript:void(0);">删除</a>
              </lz-popconfirm>
            </space>
          </space>
        </template>
      </nested-draggable>
    </div>
  </page-content>
</template>

<script>
import {
  destroySystemModel,
  getSystemModels,
  importSystemModels,
} from '@/api/system-models'
import LzPopconfirm from '@c/LzPopconfirm'
import {
  getMessage,
  hasChildren,
  removeFromNested,
  changeListDefault,
} from '@/libs/utils'
import NestedDraggable from '@c/NestedDraggable'
import Space from '@c/Space'
import PageContent from '@c/PageContent'
import LoadingAction from '@c/LoadingAction'
import ChildrenField from './ChildrenField'
import DocPreview from '@c/DocPreview'
import _forIn from 'lodash/forIn'

export default {
  name: 'Index',
  scroll: true,
  components: {
    Space,
    NestedDraggable,
    LzPopconfirm,
    PageContent,
    LoadingAction,
    ChildrenField,
    DocPreview
  },
  data() {
    return {
      SystemModels: [],
      SystemModelsBak: '',
      validationRules: [],
      filterRules: [],
      fieldTypes: [],
      fields: [],
      // 默认展开第二级模型
      defaultExpanded: [],
    }
  },
  created() {
    this.getSystemModels()
  },
  activated() {
    // 缓存的页面，由于不会执行 created 方法，所以滚动行为，放在该钩子里
    this.$scrollResolve()
  },
  methods: {
    async getSystemModels() {
      const { data: { tree, validationRules, filterRules, fieldTypes, fields } } = await getSystemModels()
      tree.forEach((i) => {
        i.children = changeListDefault(i.children)
      })
      this.SystemModels = tree
      this.SystemModelsBak = JSON.stringify(this.SystemModels)
      _forIn(validationRules, (value,key) => {
        this.validationRules[key] = '<pre>'+JSON.stringify(value, null, 4)+'</pre>'
      })
      _forIn(filterRules, (value,key) => {
        this.filterRules[key] = '<pre>'+JSON.stringify(value, null, 4)+'</pre>'
      })
      _forIn(fieldTypes, (value,key) => {
        this.fieldTypes[key] = '<pre>'+JSON.stringify(value, null, 4).replace(/\\/g,"\\\\")+'</pre>'
      })
      _forIn(fields, (value,key) => {
        this.fields[key] = '<pre>'+JSON.stringify(value, null, 4)+'</pre>'
      })
      // this.defaultExpanded = this.SystemModels.filter(i => hasChildren(i)).map(i => i.id)

      this.$scrollResolve()
    },
    onDestroy(row) {
      return async () => {
        await destroySystemModel(row.id)
        this.$message.success(getMessage('destroyed'))
        removeFromNested(this.SystemModels, row.id)
      }
    },
    hasChildren,
    onExpand() {
      this.$refs.models.expandAll()
    },
    onCollapse() {
      this.$refs.models.collapseAll()
    },
    /**
     * 获取模型结构，仅包含 id 和 children 字段
     * @param SystemModels
     * @returns {Array}
     */
    getSystemModelStruct(SystemModels = this.SystemModels) {
      const struct = []
      SystemModels.forEach((i) => {
        struct.push({
          id: i.id,
          children: hasChildren(i)
            ? this.getSystemModelStruct(i.children)
            : undefined,
        })
      })
      return struct
    },
    onExport() {
      const exportStruct = this.SystemModels
      exportStruct.forEach((i) => {
        i.children.forEach((j) => {
          if (j.options) {
            j.options = JSON.stringify(j.options)
          }
        })
      })
      const blob = new Blob(
        [JSON.stringify(exportStruct, null, 2)],
        { type: 'application/json' },
      )
      
      const link = document.createElement('a')
      link.href = window.URL.createObjectURL(blob)
      link.download = '模型配置'
      link.click()

      window.URL.revokeObjectURL(link.href)
    },
    async importSystemModels({ file }) {
      const fd = new FormData()
      fd.append('file', file)

      const { data } = await importSystemModels(fd)
      this.SystemModels = data
      this.$message.success(getMessage('updated'))
    },
    confirmImport(file) {
      return new Promise((resolve, reject) => {
        this.$confirm({
          title: '提示',
          content: '是否替换所有模型配置？',
          onOk() {
            resolve()
          },
        })
      })
    },
  },
}
</script>

<style lang="less">
@import "~@/styles/vars";

.system-models {
  width: 1100px;

  .id {
    width: 40px;
    display: inline-block;
    text-align: center;
    font-weight: bolder;
  }

  .path {
    color: @primary-color;
  }

  .item-wrap {
    overflow: hidden;
    white-space: nowrap;
    text-overflow: ellipsis;
  }
}

.header-actions {
  width: 100%;
  overflow-x: auto;
}
</style>
